﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace DataProcess
{
    namespace Xml
    {
        /// <summary>
        /// Xml的指定项
        /// </summary>
        public enum XmlItemType
        {
            /// <summary>
            /// 标签内容
            /// </summary>
            InnerText,
            /// <summary>
            /// 属性
            /// </summary>
            Attributes,
            /// <summary>
            /// 标签名
            /// </summary>
            Name
        }
        /// <summary>
        /// Xml处理
        /// </summary>
        public class XmlCase : XmlDocument
        {
            private string nodepath = "";
            public string Xpath
            {
                set
                {
                    nodepath = value;
                    NodeList = SelectSingleNode(value).ChildNodes;
                }
                get => nodepath;
            }
            private XmlNodeList nodeList;
            public XmlNodeList NodeList
            {
                get => nodeList;
                set => nodeList = value;
            }
            /// <summary>
            /// 实例化，设置默认节点路径
            /// </summary>
            /// <param name="path"></param>
            public XmlCase(string path)
            {
                Load(path);
            }
            /// <summary>
            /// 默认的初始化
            /// </summary>
            public XmlCase()
            {

            }

            /// <summary>
            /// 创建一个xml文件
            /// </summary>
            /// <param name="RootElement">根节点名</param>
            /// <param name="SaveLocation">储存位置</param>
            public void MakeXml(string RootElement, string SaveLocation)
            {
                CreateXml(RootElement).Save(SaveLocation);
            }
            /// <summary>
            /// 创建一个xml文件
            /// </summary>
            /// <param name="root">根节点名</param>
            /// <param name="saveLocation">文件储存位置</param>
            /// <param name="AttributesName">属性名集合</param>
            /// <param name="attributesValues">对应属性名的值的集合</param>
            public void MakeXml(string root, string saveLocation, string[] AttributesName, string[] attributesValues)
            {
                if (AttributesName.Length != attributesValues.Length)
                {
                    throw new Exception("属性名的个数应与属性值的个数相同");
                }

                XmlDocument document = CreateXml(root);
                XmlElement XMLroot = document.FirstChild as XmlElement;
                for (int i = 0; i < AttributesName.Length; i++)
                {
                    XMLroot.SetAttribute(AttributesName[i], attributesValues[i]);
                }

                document.Save(saveLocation);
            }
            private XmlDocument CreateXml(string root)
            {
                XmlDocument doc = new XmlDocument();
                XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
                doc.AppendChild(dec);
                XmlElement XMLroot = doc.CreateElement(root);
                return doc;
            }
            /// <summary>
            /// 计数Xml中特定节点下的所有子节点
            /// </summary>
            /// <param name="nodepath">需要计数的母节点路径</param>
            /// <returns></returns>
            public int XmlNodeCount(string nodepath)
            {
                return SelectSingleNode(nodepath).ChildNodes.Count;
            }
            /// <summary>
            /// 显示当前Xml节点下的个数
            /// </summary>
            /// <returns></returns>
            public int XmlNodeCount()
            {
                return NodeList.Count;
            }
            /// <summary>
            /// 返回Innertext
            /// </summary>
            /// <param name="index">需要返回项的序号</param>
            /// <returns></returns>
            public string XmlGetInnerText(int index)
            {
                return NodeList.Item(index).InnerText;
            }
            /// <summary>
            /// 返回InnerText的值
            /// </summary>
            /// <param name="InnerName">需要返回项的标签名</param>
            /// <returns></returns>
            public string XmlGetInnerText(string InnerName)
            {
                int index = XmlItemIndex(InnerName);
                return nodeList.Item(index).InnerText;
            }
            /// <summary>
            /// 返回某个节点下的节点列表
            /// </summary>
            /// <param name="type">需要返回的值的类型</param>
            /// <param name="AttributesName">如果选择了属性类型，需要填写属性名</param>
            /// <returns></returns>
            public List<string> XmlItemList(XmlItemType type = XmlItemType.InnerText, string AttributesName = "")
            {
                List<string> res = new List<string>();
                switch (type)
                {
                    case XmlItemType.InnerText:
                        for (int i = 0; i < nodeList.Count; i++)
                        {
                            res.Add(nodeList.Item(i).InnerText);
                        }

                        break;
                    case XmlItemType.Attributes:
                        for (int i = 0; i < nodeList.Count; i++)
                        {
                            res.Add(nodeList.Item(i).Attributes[AttributesName].Value);
                        }

                        break;
                    case XmlItemType.Name:
                        for (int i = 0; i < nodeList.Count; i++)
                        {
                            res.Add(nodeList.Item(i).Name);
                        }

                        break;
                }
                return res;
            }
            /// <summary>
            /// 返回xml中节点的索引位
            /// </summary>
            /// <param name="value">需要返回项的标签内容</param>
            /// <param name="type">需要查找的类型</param>
            /// <returns></returns>
            public int XmlItemIndex(string value, XmlItemType type = XmlItemType.Name)
            {
                int index = -1;
                for (int i = 0; i < nodeList.Count; i++)
                {
                    switch (type)
                    {
                        case XmlItemType.Name:
                            if (nodeList.Item(i).Name.Equals(value))
                            {
                                index = i;
                                break;
                            }
                            break;
                        case XmlItemType.InnerText:
                            if (nodeList.Item(i).InnerText.Equals(value))
                            {
                                index = i;
                                break;
                            }
                            break;
                        case XmlItemType.Attributes:
                            for (int j = 0; j < nodeList.Item(i).Attributes.Count; j++)
                            {
                                if (nodeList.Item(i).Attributes[j].Value.Equals(value))
                                {
                                    index = i;
                                    break;
                                }
                            }

                            break;
                    }
                }
                return index;
            }
            /// <summary>
            /// 获取某一个的属性值
            /// </summary>
            /// <param name="Innername">需要返回项的标签内容</param>
            /// <param name="AttributeName">需要返回的属性名</param>
            /// <returns></returns>
            public string XmlGetItemValue(string Innername, string AttributeName)
            {
                int index = -1;
                string result = "";
                index = XmlItemIndex(Innername);
                if (index != -1)
                {
                    result = nodeList.Item(index).Attributes[AttributeName].Value;
                }
                return result;
            }
            /// <summary>
            /// 获取某一个的属性值
            /// </summary>
            /// <param name="index">需要返回项的的序号</param>
            /// <param name="AttributeName">需要返回的属性名</param>
            /// <returns></returns>
            public string XmlGetItemValue(int index, string AttributeName)
            {
                return nodeList.Item(index).Attributes[AttributeName].Value;
            }
            /// <summary>
            /// 设置某一项的标签内容
            /// </summary>
            /// <param name="index">需要修改项的序号</param>
            /// <param name="value">修改的值</param>
            /// <returns></returns>
            public bool XmlChangeItemInnerText(int index, string value)
            {
                try
                {
                    nodeList.Item(index).InnerText = value;
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            /// <summary>
            /// 修改某一项属性
            /// </summary>
            /// <param name="index">需要修改项的序号</param>
            /// <param name="AttributeName">需要修改的属性名</param>
            /// <param name="value">需要修改的属性值</param>
            public bool XmlChangeItemAttribute(int index, string AttributeName, string value)
            {
                try
                {
                    nodeList.Item(index).Attributes[AttributeName].Value = value;
                    return true;
                }
                catch
                {
                    return false;
                }
            }

            /// <summary>
            /// 删除某一项
            /// </summary>
            /// <param name="InnerName">需要删除项的标签内容</param>
            /// <returns></returns>
            public void XmlDeleteItem(string InnerName)
            {
                XmlNode xmlNode = SelectSingleNode(nodepath);
                XmlNodeList nodeList = xmlNode.ChildNodes;
                int index = 0;
                index = XmlItemIndex(InnerName);
                if (index != -1)
                {
                    xmlNode.RemoveChild(nodeList.Item(index));
                }
            }
            /// <summary>
            /// 删除某一项
            /// </summary>
            /// <param name="index">需要删除项的标签序号</param>
            /// <returns></returns>
            public void XmlDeleteItem(int index)
            {
                XmlNode xmlNode = SelectSingleNode(nodepath);
                XmlNodeList nodeList = xmlNode.ChildNodes;
                xmlNode.RemoveChild(nodeList.Item(index));
            }
            /// <summary>
            /// 增加一项
            /// </summary>
            /// <param name="Innername">增加项的标签名</param>
            /// <param name="InnerText">增加项的标签内容</param>
            /// <param name="AttributesName">增加项目的属性（可多个，需要与值相对应）</param>
            /// <param name="AttributeValues">增加项的属性值（可多个，需要与属性排序相对应）</param>
            /// <returns></returns>
            public void XmlAddItem(string Innername, string InnerText, string[] AttributesName, string[] AttributeValues)
            {
                XmlNode xmlNode = SelectSingleNode(nodepath);
                XmlElement xmlElement = CreateElement(Innername);
                for (int i = 0; i < AttributesName.Length; i++)
                {
                    xmlElement.SetAttribute(AttributesName[i], AttributeValues[i]);
                }
                xmlElement.InnerText = InnerText;
                xmlNode.AppendChild(xmlElement);
            }
            /// <summary>
            /// 增加一项
            /// </summary>
            /// <param name="Innername">增加项的标签名</param>
            /// <param name="InnerText">增加项的标签内容</param>
            /// <returns></returns>
            public void XmlAddItem(string Innername, string InnerText)
            {
                XmlNode xmlNode = SelectSingleNode(nodepath);
                XmlElement xmlElement = CreateElement(Innername);
                xmlElement.InnerText = InnerText;
                xmlNode.AppendChild(xmlElement);
            }
        }
    }
}
